import * as Cesium from 'cesium';

/**
 * 数据转换工具类
 */
export class DataUtils {
  
  /**
   * 将JTS Point转换为Cesium Cartesian3
   * @param {Object} point - JTS Point对象 {x: longitude, y: latitude}
   * @returns {Cesium.Cartesian3}
   */
  static pointToCartesian3(point) {
    if (!point || point.x === undefined || point.y === undefined) {
      console.warn('Invalid point data:', point);
      return null;
    }
    return Cesium.Cartesian3.fromDegrees(point.x, point.y, 0);
  }
  
  /**
   * 将JTS LineString转换为Cesium positions数组
   * @param {Object} lineString - JTS LineString对象
   * @returns {Array<Cesium.Cartesian3>}
   */
  static lineStringToPositions(lineString) {
    if (!lineString || !lineString.coordinates) {
      console.warn('Invalid lineString data:', lineString);
      return [];
    }
    
    return lineString.coordinates.map(coord => 
      Cesium.Cartesian3.fromDegrees(coord.x, coord.y, 0)
    );
  }
  
  /**
   * 将JTS Polygon转换为Cesium polygon hierarchy
   * @param {Object} polygon - JTS Polygon对象
   * @returns {Cesium.PolygonHierarchy}
   */
  static polygonToHierarchy(polygon) {
    if (!polygon || !polygon.coordinates || !polygon.coordinates[0]) {
      console.warn('Invalid polygon data:', polygon);
      return null;
    }
    
    const outerRing = polygon.coordinates[0];
    const positions = outerRing.map(coord => 
      Cesium.Cartesian3.fromDegrees(coord.x, coord.y, 0)
    );
    
    return new Cesium.PolygonHierarchy(positions);
  }
  
  /**
   * 将路径点数组转换为Cesium轨迹所需的格式
   * @param {Array} pathPoints - 路径点数组 [{longitude, latitude}, ...]
   * @returns {Array<Object>} [{x, y, z}, ...]
   */
  static pathPointsToTrackPositions(pathPoints) {
    if (!pathPoints || !Array.isArray(pathPoints)) {
      return [];
    }
    
    return pathPoints.map(point => ({
      x: point.longitude,
      y: point.latitude,
      z: 1
    }));
  }
  
  /**
   * 格式化设备状态显示文本
   * @param {string} status - 设备状态
   * @returns {string}
   */
  static formatDeviceStatus(status) {
    if (!status) return '未知状态';
    const statusMap = {
      'WORKING': '工作中',
      'IDLE': '空闲',
      'OFFLINE': '离线'
    };
    return statusMap[status] || status;
  }
  
  /**
   * 获取设备状态对应的颜色
   * @param {string} status - 设备状态
   * @returns {Cesium.Color}
   */
  static getDeviceStatusColor(status) {
    if (!status) return Cesium.Color.GRAY;
    const colorMap = {
      'WORKING': Cesium.Color.GREEN,
      'IDLE': Cesium.Color.YELLOW,
      'OFFLINE': Cesium.Color.RED
    };
    return colorMap[status] || Cesium.Color.GRAY;
  }
  
  /**
   * 计算两点之间的距离（米）
   * @param {number} lon1 - 第一个点的经度
   * @param {number} lat1 - 第一个点的纬度
   * @param {number} lon2 - 第二个点的经度
   * @param {number} lat2 - 第二个点的纬度
   * @returns {number} 距离（米）
   */
  static calculateDistance(lon1, lat1, lon2, lat2) {
    const point1 = Cesium.Cartesian3.fromDegrees(lon1, lat1);
    const point2 = Cesium.Cartesian3.fromDegrees(lon2, lat2);
    return Cesium.Cartesian3.distance(point1, point2);
  }
  
  /**
   * 格式化日期时间
   * @param {string|Date} dateTime - 日期时间
   * @returns {string}
   */
  static formatDateTime(dateTime) {
    if (!dateTime) return '';
    const date = new Date(dateTime);
    return date.toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit'
    });
  }
  
  /**
   * 格式化距离显示
   * @param {number} distance - 距离（米）
   * @returns {string}
   */
  static formatDistance(distance) {
    if (distance < 1000) {
      return `${distance.toFixed(1)}米`;
    } else {
      return `${(distance / 1000).toFixed(2)}公里`;
    }
  }
}

/**
 * 空间分析工具类
 */
export class SpatialUtils {
  
  /**
   * 计算多边形面积
   * @param {Array<Cesium.Cartesian3>} positions - 多边形顶点
   * @returns {number} 面积（平方米）
   */
  static calculatePolygonArea(positions) {
    if (!positions || positions.length < 3) {
      return 0;
    }
    
    // 转换为经纬度坐标
    const cartographics = positions.map(pos => 
      Cesium.Cartographic.fromCartesian(pos)
    );
    
    // 使用球面几何计算面积
    let area = 0;
    const n = cartographics.length;
    
    for (let i = 0; i < n; i++) {
      const j = (i + 1) % n;
      const xi = cartographics[i].longitude;
      const yi = cartographics[i].latitude;
      const xj = cartographics[j].longitude;
      const yj = cartographics[j].latitude;
      
      area += (xj - xi) * (yj + yi);
    }
    
    // 将弧度转换为面积（平方米）
    // 使用地球半径近似计算
    const earthRadius = 6371000; // 地球半径（米）
    area = Math.abs(area) / 2.0;
    area = area * earthRadius * earthRadius;
    
    return area;
  }
  
  /**
   * 判断点是否在多边形内
   * @param {Cesium.Cartesian3} point - 点
   * @param {Array<Cesium.Cartesian3>} polygonPositions - 多边形顶点
   * @returns {boolean}
   */
  static isPointInPolygon(point, polygonPositions) {
    // 将3D坐标转换为经纬度
    const pointCartographic = Cesium.Cartographic.fromCartesian(point);
    const polygonCartographics = polygonPositions.map(pos => 
      Cesium.Cartographic.fromCartesian(pos)
    );
    
    // 使用射线法判断点是否在多边形内
    let isInside = false;
    const x = pointCartographic.longitude;
    const y = pointCartographic.latitude;
    
    for (let i = 0, j = polygonCartographics.length - 1; i < polygonCartographics.length; j = i++) {
      const xi = polygonCartographics[i].longitude;
      const yi = polygonCartographics[i].latitude;
      const xj = polygonCartographics[j].longitude;
      const yj = polygonCartographics[j].latitude;
      
      if (((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)) {
        isInside = !isInside;
      }
    }
    
    return isInside;
  }
  
  /**
   * 计算轨迹与地块的相交面积（简化算法）
   * @param {Array<Cesium.Cartesian3>} trackPositions - 轨迹点
   * @param {Array<Cesium.Cartesian3>} parcelPositions - 地块边界点
   * @param {number} workWidth - 作业宽度（米）
   * @returns {number} 作业面积（平方米）
   */
  static calculateWorkingArea(trackPositions, parcelPositions, workWidth = 5) {
    if (!trackPositions || trackPositions.length < 2) {
      return 0;
    }
    
    let totalArea = 0;
    
    // 简化算法：计算轨迹长度乘以作业宽度，再检查是否在地块内
    for (let i = 0; i < trackPositions.length - 1; i++) {
      const start = trackPositions[i];
      const end = trackPositions[i + 1];
      
      // 计算线段中点
      const midPoint = Cesium.Cartesian3.midpoint(start, end, new Cesium.Cartesian3());
      
      // 检查中点是否在地块内
      if (this.isPointInPolygon(midPoint, parcelPositions)) {
        // 计算线段长度
        const segmentLength = Cesium.Cartesian3.distance(start, end);
        totalArea += segmentLength * workWidth;
      }
    }
    
    return totalArea;
  }
}